# -*- coding:utf-8 -*-
"""
作者：13642224036
日期：2023年06月20日
"""
import requests
import json
import pandas as pd
import copy
import time
from requests_html import HTMLSession
from pyecharts import options as opts
from pyecharts.charts import Map
from pyecharts.charts import WordCloud
from pyecharts.globals import SymbolType
from pyecharts.charts import Bar
from pyecharts.faker import Faker
from pyecharts.charts import Pie
from pyecharts.faker import Faker
from pyecharts.charts import WordCloud
from pyecharts.globals import SymbolType


# 数据获取
def boss_data(用户输入地区, 用户输入职位):
    地区编码字典 = {
        '广州': '101280100',
        '深圳': '101280600',
        '北京': '101010100',
        '上海': '101020100',
        '杭州': '101210100',
        '天津': '101030100',
        '西安': '101110100',
        '苏州': '101190400',
        '武汉': '101200100',
        '厦门': '101230200',
        '长沙': '101250100',
        '成都': '101270100',
        '郑州': '101180100',
        '重庆': '101040100',
        '汕头': '101280500'
    }
    url = "https://www.zhipin.com/wapi/zpgeek/search/joblist.json"
    payload = {
        'scene': '1',
        'query': '',
        'city': 地区编码字典[用户输入地区],
        'key': 用户输入职位,
        'dq': 地区编码字典[用户输入地区],
        'experience': '',
        'payType': '',
        'partTime': '',
        'degree': '',
        'industry': '',
        'scale': '',
        'stage': '',
        'position': '',
        'jobType': '',
        'salary': '',
        'multiBusinessDistrict': '',
        'multiSubway': '',
        'page': '1',
        'pageSize': '30'
    }
    session = HTMLSession()
    headers = {
        'authority': 'www.zhipin.com',
        'method': 'GET',
        'path': '/wapi/zpgeek/search/joblist.json?scene=1&query=&city=100010000&experience=&payType=&partTime=&degree=&industry=&scale=&stage=&position=&jobType=&salary=&multiBusinessDistrict=&multiSubway=&page=1&pageSize=30',
        'scheme': 'https',
        'accept': 'application/json, text/plain, */*',
        'accept-encoding': 'gzip, deflate, br',
        'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'cookie': 'wd_guid=2900a015-2f57-4466-86d0-2a9f6877d9a0; historyState=state; _bl_uid=n7l3kizp10brs1y69ehk0e99sF0e; YD00951578218230%3AWM_TID=VIw9tj27tWpBRUEVVRPQgDwCpFwgZfvY; gdxidpyhxdE=ZYa2tmmZAteCmXTIKw2LviLi%2F6KWGUbIHNUf5dvTolAwCqQalcxT%5ChDCa6mXP%2B2vJMA1nfdnKmrGjTi7gn2%5CBXSZcBvA7bQBrJehGUsilNWdfUnKcjfCn%5CblDCmcU3NAsc7ReSHeQqwv%2FhwREbWVY90c7slGsaTjPxi%2FsSBwSMZ8fBl5%3A1686107608452; YD00951578218230%3AWM_NI=9mxeknAW7a%2B2XmiBqYL%2B3q8L5Gz2hyopADbaQrQ195UfSMWYcQiJ%2F9sxn2JvIWBd5hxoUuiX7YUpzHTx7KzHu8nA42lrXN3UtlEiFQTS5DI68fz18iWwonv%2B8xP1THI3U1o%3D; YD00951578218230%3AWM_NIKE=9ca17ae2e6ffcda170e2e6eeb6cc67e9bdfbb0e76a82b88ba2c55b939f9e83d86d8b86afd9cd66a599bfb4cd2af0fea7c3b92afbb3b886ea668389f982aa3a9cb3a7a3f45390f5fd92bb48f799b6d3eb73adb08fa5e16b93ae9fd2bc3f97ba9daed653a18fa7abae33b1a8a2d3c97e8b898e85b864bcb19b96ec54f5879b91f94498a8f9acf944b7e8a2a2b73ab0ae98afb25fb8b48b8ac55b988dfba5cc3efcbab6d2bb6395a9a18ff521fca8a0d2d7448bed9bd2ee37e2a3; lastCity=100010000; __fid=b5aea7c6126b549b15c2b4b0ed5005ed; Hm_lvt_194df3105ad7148dcf2b98a91b5e727a=1687180513,1687248425,1687330606,1687340938; Hm_lpvt_194df3105ad7148dcf2b98a91b5e727a=1687349925; __c=1687340937; __g=-; __a=77455186.1684936079.1687330607.1687340937.217.10.25.217; __zp_stoken__=3912eOEhrTjtAMyoyYlE3dSAXCycHUxl8Em5qKQ17ej5oeCN0IkJ%2FfnNwZFgHXkkhFyYHJF1rAzwCWQhkdFh8VgowFgNPFyoYETtnK1QjUHcjQUNnQzd5WTs%2FHVR1KBhqVR81X0dDfEBLZXQ%3D; __zp_seo_uuid__=b3f5f8fe-fa15-40ae-b679-621573c8172a; __l=r=https%3A%2F%2Fcn.bing.com%2F&l=%2Fjob_detail%2F&s=1; __zp_sseed__=bqRdnJ1Xea1Cjw4rCjFxz0hoCmXGWFBBv9zdnnMNgzU=; __zp_sname__=4ac9435f; __zp_sts__=1687350026551',
        'sec-ch-ua': '"Not.A/Brand";v="8", "Chromium";v="114", "Microsoft Edge";v="114"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sec-fetch-dest': 'empty',
        'sec-fetch-mode': 'cors',
        'sec-fetch-site': 'same-origin',
        'token': 'EPNWvHf06h7Gvp7Z',
        'traceid': 'AAA4A0A6-0E97-442F-9CDD-C69397BC7225',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.51',
        'x-requested-with': 'XMLHttpRequest',
        'zp_token': 'V1R9onE-L131ZjVtRvxxgaLyy46jzQzSw~'
    }

    r = session.get(url=url, params=payload, headers=headers)
    response_data = r.json()
    jobL = response_data['zpData']['jobList']

    # 翻页
    payload_page = []
    for i in range(30):
        payload_new = copy.deepcopy(payload)
        payload_new['page'] = i
        payload_page.append(payload_new)
    response_df = []
    for i in payload_page:
        r = session.get(url=url, params=payload, headers=headers)
        response_data = r.json()
        df = pd.json_normalize(jobL)
        response_df.append(df)

    # 整理
    df = pd.concat(response_df)
    key = payload['key']
    output_time = str(time.localtime().tm_mon) \
                  + str(time.localtime().tm_mday) + '_' \
                  + str(time.localtime().tm_hour) \
                  + str(time.localtime().tm_min)
    df.to_excel(key + '_boss_' + output_time + '.xlsx')

    # 数据可视化——地区分布
def boss_dq(用户输入地区, 用户输入职位):
    output_time = str(time.localtime().tm_mon) \
                  + str(time.localtime().tm_mday) + '_' \
                  + str(time.localtime().tm_hour) \
                  + str(time.localtime().tm_min)
    df = pd.read_excel(f'{用户输入职位}_boss_{output_time}.xlsx')
    df_key = df[
        ['jobName', 'salaryDesc', 'jobLabels', 'jobDegree', 'skills', 'areaDistrict', 'brandScaleName', 'brandName',
         'brandIndustry']]
    # 地区分布
    df_key_dq = df_key['areaDistrict'].value_counts()

    地区 = df_key_dq.index.tolist()
    岗位个数 = df_key_dq.values.tolist()
    c = (
        Map(init_opts=opts.InitOpts(width="800x",
                                height="550px",))
        .add(用户输入地区, [list(z) for z in zip(地区, 岗位个数)], 用户输入地区)
        .set_global_opts(
            title_opts=opts.TitleOpts(title='Map-' + 用户输入地区 + '地图'), visualmap_opts=opts.VisualMapOpts(),
            legend_opts=opts.LegendOpts(pos_top='20')
        )

    )
    return c


    # 数据可视化——学历要求
def boss_xl(用户输入地区, 用户输入职位):
    output_time = str(time.localtime().tm_mon) \
                  + str(time.localtime().tm_mday) + '_' \
                  + str(time.localtime().tm_hour) \
                  + str(time.localtime().tm_min)
    df = pd.read_excel(f'{用户输入职位}_boss_{output_time}.xlsx')
    df_key = df[
        ['jobName', 'salaryDesc', 'jobLabels', 'jobDegree', 'skills', 'areaDistrict', 'brandScaleName', 'brandName',
         'brandIndustry']]
    df_key['jobDegree'].value_counts().index.tolist()
    df_key['jobDegree'].value_counts().values.tolist()
    bt = (
        Pie(init_opts=opts.InitOpts(width="200x",
                                height="650px",))
        .add("", [list(z) for z in zip(df_key['jobDegree'].value_counts().index.tolist(),
                                       df_key['jobDegree'].value_counts().values.tolist())])
        .set_colors(["blue", "green", "yellow","pink","grey"])
        .set_global_opts(title_opts=opts.TitleOpts(title="学历要求"),
                         legend_opts=opts.LegendOpts(pos_top='40'))
        .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))
    )
    return bt

    # 数据可视化——公司规模
def boss_gm(用户输入地区, 用户输入职位):
    output_time = str(time.localtime().tm_mon) \
                  + str(time.localtime().tm_mday) + '_' \
                  + str(time.localtime().tm_hour) \
                  + str(time.localtime().tm_min)
    df = pd.read_excel(f'{用户输入职位}_boss_{output_time}.xlsx')
    df_key = df[
        ['jobName', 'salaryDesc', 'jobLabels', 'jobDegree', 'skills', 'areaDistrict', 'brandScaleName', 'brandName',
         'brandIndustry']]
    df_key['brandIndustry']
    df_Industry = df_key['brandIndustry'].apply(lambda x: x.split('（')[0].split('/')[0].split('(')[0]).value_counts()
    df_Industry.index.tolist()
    df_Industry.values.tolist()
    df_key['brandIndustry'].value_counts()
    PM_title_words = [(df_Industry.index.tolist()[i], df_Industry.values.tolist()[i]) for i in
                      range(1, len(df_Industry.index.tolist()))]
    wd = (
        WordCloud(init_opts=opts.InitOpts(width="400x",
                                height="300px",))
        .add("", PM_title_words, word_size_range=[40, 100], shape=SymbolType.DIAMOND)
        .set_global_opts(title_opts=opts.TitleOpts(title="公司产业分布词云图"))

    )
    return wd

    # 数据可视化——平均薪资
def boss_xz(用户输入地区, 用户输入职位):
    output_time = str(time.localtime().tm_mon) \
                  + str(time.localtime().tm_mday) + '_' \
                  + str(time.localtime().tm_hour) \
                  + str(time.localtime().tm_min)
    df = pd.read_excel(f'{用户输入职位}_boss_{output_time}.xlsx')
    df_key = df[
        ['jobName', 'salaryDesc', 'jobLabels', 'jobDegree', 'skills', 'areaDistrict', 'brandScaleName', 'brandName',
         'brandIndustry']]
    df_key['salaryDesc'].value_counts()
    nonpatm = df_key[~df_key['salaryDesc'].str.contains("元/天")]
    salary_detail = nonpatm['salaryDesc'].apply(lambda x: x.split('薪')[0].split('·')).tolist()
    avg = [(int(i[0][:-1].split('-')[0]) + int(i[0][:-1].split('-')[1])) / 2 if len(i) == 1
                else round((int(i[0][:-1].split('-')[0]) + int(i[0][:-1].split('-')[1])) / 2 * int(i[1]) / 12, 1)
                for i in salary_detail]
    nonpatm['平均薪资'] = avg
    dq_avg = nonpatm.groupby('areaDistrict').agg({'平均薪资': 'median'}).query('areaDistrict != ""')
    dq_avg_values = [round(i[0], 1) for i in dq_avg.values.tolist()]
    dq_avg_index = dq_avg.index.tolist()
    zz = (
        Bar(init_opts=opts.InitOpts(width="400x",
                                height="300px",))
        .add_xaxis([i for i in dq_avg_index[1:]])
        .add_yaxis("areaDistrict", dq_avg_values[1:])
        .set_global_opts(
            title_opts=opts.TitleOpts(title="平均薪资"),
            brush_opts=opts.BrushOpts(),
            legend_opts=opts.LegendOpts(pos_top='20')
        )
    )
    return zz